/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.distschedule.slice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.distschedule.ResourceTable;
import com.example.distschedule.bean.Command;
import com.example.distschedule.bean.DeviceResult;
import com.example.distschedule.bean.RespondBase;
import com.example.distschedule.event.MessageEvent;
import com.example.distschedule.rx2.OKHttpUtilsRx2;
import com.example.distschedule.toast.XToastUtils;
import com.example.distschedule.utils.*;
import com.socks.library.KLog;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.miscservices.timeutility.Time;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.greenrobot.eventbus.EventBus;

import java.util.Locale;

import static com.example.distschedule.slice.SelectDeviceAbilitySlice.KEY_IS_SET_COMMAND;

/**
 * 加湿器控制页面
 */
public class HumidifierAbilitySlice extends AbilitySlice {
    private boolean isON = false;
    private String deviceId;
    private Slider humiditySlider;
    private Text humidifierState;
    private Image switchImg;
    private Text humiditySetupText;
    private DirectionalLayout gearBox;
    private DirectionalLayout smartDl;
    private Text muteText;
    private Image muteImage;
    private boolean isSetCommand = false;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_humidifier);

        isSetCommand = intent.getBooleanParam(KEY_IS_SET_COMMAND, false);
        deviceId = intent.getStringParam("deviceId");
        initComponents();
        initDeviceState();
    }

    private void initNetState() {
        TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        globalTaskDispatcher.asyncDispatch(() -> {
            KLog.i("async task initNetState run");
            checkDeviceNet();
        });
    }

    private void initDeviceState() {
        Text currentHumidityText = (Text) findComponentById(ResourceTable.Id_humidifier_text_humidity);
        // 从服务端获取设备信息
        OKHttpUtilsRx2.INSTANCE.getApi().getDeviceInfo(deviceId, PreferencesUtil.getUserId(getContext()))
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase<DeviceResult>>() {
                    @Override
                    public void onNext(RespondBase<DeviceResult> deviceInfo) {
                        KLog.i(deviceInfo);
                        if (deviceInfo.isSuccess() && deviceInfo.getResult().isOnline()) {
                            // 更新状态
                            String property = deviceInfo.getResult().getProperty();
                            String[] deviceState = DeviceStateUtil.getKeyValue(property,"HumidifierStatus","Humidity","HumidityHig");
                            isON = "ON".equals(deviceState[0]); // 是否打开
                            String currentHumidity = deviceState[1]; // 当前湿度
                            currentHumidityText.setText(currentHumidity + "%");
                            String setupHumidity = deviceState[2]; // 湿度设定
                            humiditySetupText.setText(String.format(Locale.CHINA, "%s", setupHumidity + "%"));
                            try {
                                if (setupHumidity == null){
                                    humiditySlider.setProgressValue(0);
                                }else {
                                    humiditySlider.setProgressValue((int) Float.parseFloat(setupHumidity));
                                }
                            } catch (NumberFormatException e) {
                                KLog.e("数据类型错误");
                                XToastUtils.error("加湿器上报数据类型错误");
                                humiditySlider.setProgressValue(0);
                            }
                            if (isON) {
                                switchImg.setPixelMap(ResourceTable.Media_icon_switch_on);
                                humidifierState.setText("已开启");
                            } else {
                                switchImg.setPixelMap(ResourceTable.Media_icon_switch_off);
                                humidifierState.setText("已关闭");
                            }

                        } else {
                            initNetState();
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        initNetState();
                    }
                });
    }

    private void checkDeviceNet() {
        Time.sleep(10 * 1000);
        OKHttpUtilsRx2.INSTANCE.getApi().getDeviceInfo(deviceId, PreferencesUtil.getUserId(getContext()))
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase<DeviceResult>>() {
                    @Override
                    public void onNext(RespondBase<DeviceResult> deviceInfo) {
                        super.onNext(deviceInfo);
                        KLog.i(deviceInfo);
                        if (deviceInfo.getResult() == null || !deviceInfo.getResult().isOnline()) {
                            XToastUtils.toast("未配网成功，请再次碰一碰重试");
                        }
                    }
                });
    }

    private void initComponents() {
        initGear();
        initMode();
        // 设置开关样式
        Switch shutdownSwitch = (Switch) findComponentById(ResourceTable.Id_humidifier_switch_shutdown);
        CommonUtil.setSwitchStyle(shutdownSwitch);
        shutdownSwitch.setClickedListener(component -> {
            XToastUtils.info("设备暂不支持，敬请期待");
        });
        switchImg = (Image) findComponentById(ResourceTable.Id_humidifier_image_switch);
        switchImg.setClickedListener(component -> switchListener());
        findComponentById(ResourceTable.Id_humidifier_img_left).setClickedListener(this::goBack);
        humidifierState = (Text) findComponentById(ResourceTable.Id_humidifier_text_switch);
        humiditySetupText = (Text) findComponentById(ResourceTable.Id_humidifier_text_bar_value);
        humiditySlider = (Slider) findComponentById(ResourceTable.Id_humidifier_slider_bar);
        humiditySlider.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean fromUser) {

            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {
                humiditySetupText.setText(String.format(Locale.CHINA, "%s", slider.getProgress() + "%"));
                if (isSetCommand) {
                    XToastUtils.toast("湿度调节不在日程控制内");
                }else {
                    sendCommand(CommandUtil.getHumidityCommand(slider.getProgress()));
                }
            }
        });

        // 顶部右侧图标
        Image rightIcon = (Image) findComponentById(ResourceTable.Id_humidifier_img_right);
        if (isSetCommand) {
            rightIcon.setPixelMap(ResourceTable.Media_icon_ok);
            rightIcon.setClickedListener(this::saveCommand);
        }else {
            rightIcon.setClickedListener(component -> {
                XToastUtils.toast("智能加湿器基于BES2600板子支持湿度属性上报、日程设置、远程开关和湿度设置等功能");
            });
        }
    }

    private void saveCommand(Component component) {
        // 将device和命令使用EventBus传出到 SelectDeviceAbilitySlice中，用于保存命令
        EventBus.getDefault().post(new MessageEvent(MessageEvent.EVENT_GET_COMMAND,
                deviceId, CommandUtil.getHumidifierStatusCommand(isON)));
        onBackPressed();
    }

    /**
     *
     */
    private void initMode() {
        smartDl = (DirectionalLayout) findComponentById(ResourceTable.Id_humidifier_dl_smart);
        DirectionalLayout muteDl = (DirectionalLayout) findComponentById(ResourceTable.Id_humidifier_dl_mute);
        muteText = (Text) findComponentById(ResourceTable.Id_humidifier_text_mute);
        muteImage = (Image) findComponentById(ResourceTable.Id_humidifier_image_mute);

        smartDl.setClickedListener(this::setSmartMode);
        muteDl.setClickedListener(this::setMuteMode);
    }

    /**
     * 设置智能模式
     */
    private void setSmartMode(Component component){
        for (int i = 0; i < smartDl.getChildCount(); i++) {
            ((Text)smartDl.getComponentAt(i)).setTextColor(new Color(getColor(ResourceTable.Color_blue)));
        }
        muteText.setTextColor(new Color(getColor(ResourceTable.Color_black)));
        muteImage.setPixelMap(ResourceTable.Media_icon_mute_unselected);
    }

    /**
     * 设置静音模式
     */
    private void setMuteMode(Component component){
        for (int i = 0; i < smartDl.getChildCount(); i++) {
            ((Text)smartDl.getComponentAt(i)).setTextColor(new Color(getColor(ResourceTable.Color_black)));
        }
        muteText.setTextColor(new Color(getColor(ResourceTable.Color_blue)));
        muteImage.setPixelMap(ResourceTable.Media_icon_mute_selected);
    }

    private void initGear(){
        gearBox = (DirectionalLayout) findComponentById(ResourceTable.Id_humidifier_dl_gear_box);
        changeGear(1); // 默认一档
        int count = gearBox.getChildCount();
        for (int i = 0; i < count; i++) {
            int gear = i + 1;
            gearBox.getComponentAt(i).setClickedListener(component -> {
                XToastUtils.info("设备暂无档位，敬请期待");
                changeGear(gear);
            });
        }
    }

    private void changeGear(int gear){
        if (gear > 3 || gear < 1){
            KLog.e("档位错误");
            return;
        }
        int count = gearBox.getChildCount();
        for (int i = 0; i < count; i++) {
            setGearStyle(gearBox.getComponentAt(i),i+1 == gear);
        }

    }

    private void setGearStyle(Component component,boolean isCheck){
        ShapeElement backgroundElement = new ShapeElement();
        backgroundElement.setRgbColor(isCheck?RgbColor.fromArgbInt(0xffffffff):RgbColor.fromArgbInt(0x00000000));
        backgroundElement.setCornerRadius(Util.vp2px(getContext(),20));
        component.setBackground(backgroundElement);
        if (component instanceof Text){
            Color blue = new Color(getColor(ResourceTable.Color_blue));
            Color black = new Color(getColor(ResourceTable.Color_black));
            ((Text) component).setTextColor(isCheck?blue:black);
        }
    }

    private void goBack(Component component) {
        onBackPressed();
    }

    private void switchListener() {
        isON = !isON;
        if (isON) {
            switchImg.setPixelMap(ResourceTable.Media_icon_switch_on);
            humidifierState.setText("已开启");
        } else {
            switchImg.setPixelMap(ResourceTable.Media_icon_switch_off);
            humidifierState.setText("已关闭");
        }

        if (!isSetCommand){
            sendCommand(CommandUtil.getHumidifierStatusCommand(isON));
        }
    }

    /**
     * 发送命令
     *
     * @param command 命令
     */
    private void sendCommand(Command command) {
        JSONObject body = new JSONObject();
        body.put("commandName", command.getCommandName());
        body.put("serviceId", command.getServiceId());
        body.put("value", command.getValue());
        OKHttpUtilsRx2.INSTANCE.getApi().sendCommand(deviceId,
                RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), JSON.toJSONString(body)))
                .compose(OKHttpUtilsRx2.INSTANCE.ioMain())
                .subscribe(new OKHttpUtilsRx2.SubjectImpl<RespondBase>() {
                    @Override
                    public void onNext(RespondBase respond) {
                        super.onNext(respond);
                        if (respond.isSuccess()) {
                            XToastUtils.toast("控制命令发送成功");
                        }
                    }
                });
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
